package com.difsonapps.android.joinme;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;

import com.difsonapps.android.joinme.R;
import com.difsonapps.android.joinme.db.Contact;
import com.difsonapps.android.joinme.db.DatabaseHandler;
import com.difsonapps.android.reimpl.CustomCursorAdapter;

import android.app.Activity;
import android.app.Fragment;
import android.app.ListActivity;
import android.app.ListFragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ContentResolver;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.FrameLayout.LayoutParams;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SimpleCursorAdapter;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView;

public class ListContactFragment extends Fragment {
	SimpleCursorAdapter mAdapter;
	MatrixCursor mMatrixCursor;	
	View rootView;
	DatabaseHandler db;
	public ListView lstContacts;
	Map<String, Contact> mapOfContactDb;
	TreeMap<Integer, Object> sections = new TreeMap<Integer, Object>();
	// This is the select criteria
	static final String SELECTION = "((" + ContactsContract.Data.DISPLAY_NAME+ " NOTNULL) AND (" + ContactsContract.Data.DISPLAY_NAME+ " != '' ) AND (" +ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER+ " > 0))";
	private final String TAG = this.getClass().getSimpleName();
	
	  ListViewContactsLoader listViewContactsLoader= null;
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		if(rootView!=null)
			return rootView;
		if(db==null)
		{
			 db = new DatabaseHandler(this.getActivity().getApplicationContext());
		}
		mapOfContactDb = db.getMapContacts();
		
		Log.e(TAG, "[onCreateView]");
		 rootView = inflater.inflate(R.layout.fragment_listcontact, container,
				false);
	     // The contacts from the contacts content provider is stored in this cursor
        mMatrixCursor = new MatrixCursor(new String[] { "_id","photo","name","status"} );
        
        // Adapter to set data in the listview
        mAdapter = new SimpleCursorAdapter(getActivity().getBaseContext(),
                R.layout.contact_list,
                mMatrixCursor,
                new String[] { "photo","name","status"},
                new int[] { R.id.iv_photo,R.id.tv_name,R.id.tv_status}, 0);
        
        	// Getting reference to listview
            lstContacts = (ListView) rootView.findViewById(R.id.lst_contacts);
            
            lstContacts.setOnItemClickListener(new OnItemClickListener(){
            	
            	public void onItemClick(AdapterView<?> parent, View view, int position, long arg3) 
                {
                    Cursor cur = (Cursor) mAdapter.getItem(position);
                    cur.moveToPosition(position);
                    String id = cur.getString(cur.getColumnIndexOrThrow("_id"));

                    Intent intent = new Intent(getActivity(), ContactDetailActivity.class);
                    Bundle bundle = new Bundle();
                    bundle.putString ("id", id);
                    intent.putExtras(bundle);

                    startActivity(intent);
                }
            });
            	   
       
        // Setting the adapter to listview
        lstContacts.setAdapter(mAdapter);        
        //lstContacts.setDivider(getResources().getDrawable(R.drawable.list_divider));
        
     
	
        
        // Creating an AsyncTask object to retrieve and load listview with contacts
         listViewContactsLoader = new ListViewContactsLoader();
        
        // Starting the AsyncTask process to retrieve and load listview with contacts
        listViewContactsLoader.execute();     
        
	 	
		return rootView;
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
	   	Log.e(TAG, "[onCreate]");
		setRetainInstance(true);
		}
	
	
	@Override
	public void onDestroy() {
		super.onDestroy();
	   	Log.e(TAG, "[onDestroy]");
		if(listViewContactsLoader!=null)
		{
			listViewContactsLoader.cancel(true);
		}
		}
	
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }    

    private class ListViewContactsLoader extends AsyncTask<Void, Void, Cursor>{   	

  		@Override
  		protected Cursor doInBackground(Void... params) {
  			Uri contactsUri = ContactsContract.Contacts.CONTENT_URI;
  			
  			// Querying the table ContactsContract.Contacts to retrieve all the contacts
  			Cursor contactsCursor = getActivity().getContentResolver().query(contactsUri, null, SELECTION, null, 
  									ContactsContract.Contacts.DISPLAY_NAME + " ASC ");
  			int offset = 0, i = 0;
  			if(contactsCursor.moveToFirst()){
  				do{
  					
  					long contactId = contactsCursor.getLong(contactsCursor.getColumnIndex("_ID"));
  					
  					
  					Uri dataUri = ContactsContract.Data.CONTENT_URI;
  					
  					// Querying the table ContactsContract.Data to retrieve individual items like
  					// home phone, mobile phone, work email etc corresponding to each contact 
  					Cursor dataCursor = getActivity().getContentResolver().query(dataUri, null, 
  											ContactsContract.Data.CONTACT_ID + "=" + contactId, 
  											null, null);
  					
  					
  					String displayName="";
  					String nickName="";
  					String homePhone="";
  					String number=null;
  					String mobilePhone="";
  					String workPhone="";
  					String photoPath="" + R.drawable.ic_default_person_min;
  					byte[] photoByte=null;
  					String homeEmail="";
  					String workEmail="";
  					String companyName="";
  					String title="";
  					String status=getString(R.string.invite).toUpperCase( Locale.getDefault());
  					
  					
  					
  					if(dataCursor.moveToFirst()){
  						// Getting Display Name
  						displayName = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME ));
  						do{
  												
  							// Getting NickName
  							if(dataCursor.getString(dataCursor.getColumnIndex("mimetype")).equals(ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE))
  								nickName = dataCursor.getString(dataCursor.getColumnIndex("data1"));
  							
  							// Getting Phone numbers
  							if(dataCursor.getString(dataCursor.getColumnIndex("mimetype")).equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)){
  								switch(dataCursor.getInt(dataCursor.getColumnIndex("data2"))){
  									case ContactsContract.CommonDataKinds.Phone.TYPE_HOME : 
  										homePhone = dataCursor.getString(dataCursor.getColumnIndex("data1"));
  										break;
  									case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE : 
  										mobilePhone = dataCursor.getString(dataCursor.getColumnIndex("data1"));
  										break;
  									case ContactsContract.CommonDataKinds.Phone.TYPE_WORK : 
  										workPhone = dataCursor.getString(dataCursor.getColumnIndex("data1"));
  										break;	
  								}
  							}
  							
  							// Getting EMails
  							if(dataCursor.getString(dataCursor.getColumnIndex("mimetype")).equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE ) ) {									
  								switch(dataCursor.getInt(dataCursor.getColumnIndex("data2"))){
  									case ContactsContract.CommonDataKinds.Email.TYPE_HOME : 
  										homeEmail = dataCursor.getString(dataCursor.getColumnIndex("data1"));
  										break;
  									case ContactsContract.CommonDataKinds.Email.TYPE_WORK : 
  										workEmail = dataCursor.getString(dataCursor.getColumnIndex("data1"));
  										break;										
  								}
  							}
  							
  							// Getting Organization details
  							if(dataCursor.getString(dataCursor.getColumnIndex("mimetype")).equals(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE)){
  								companyName = dataCursor.getString(dataCursor.getColumnIndex("data1"));
  								title = dataCursor.getString(dataCursor.getColumnIndex("data4"));
  							}
  								
  							// Getting Photo	
  							if(dataCursor.getString(dataCursor.getColumnIndex("mimetype")).equals(ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)){								
  								photoByte = dataCursor.getBlob(dataCursor.getColumnIndex("data15"));
  								
  								if(photoByte != null) {							
  									Bitmap bitmap = BitmapFactory.decodeByteArray(photoByte, 0, photoByte.length);
  									
  									// Getting Caching directory 
  				                    File cacheDirectory = getActivity().getBaseContext().getCacheDir();
  	
  				                    // Temporary file to store the contact image 
  				                    File tmpFile = new File(cacheDirectory.getPath() + "/wpta_"+contactId+".png");
  	
  				                    // The FileOutputStream to the temporary file
  				                    try {
  										FileOutputStream fOutStream = new FileOutputStream(tmpFile);
  										
  										// Writing the bitmap to the temporary file as png file
  					                    bitmap.compress(Bitmap.CompressFormat.PNG,100, fOutStream);
  	
  					                    // Flush the FileOutputStream
  					                    fOutStream.flush();
  	
  					                    //Close the FileOutputStream
  					                    fOutStream.close();
  	
  									} catch (Exception e) {
  										e.printStackTrace();
  									}
  	
  				                    photoPath = tmpFile.getPath();
  								}
  								
  							}
  							
  						}while(dataCursor.moveToNext());					
  						
  						String details = "";
  						
  						// Concatenating various information to single string
  						
  						
  						if(homePhone != null && !homePhone.equals("") )
  							number = homePhone;
  						if(workPhone != null && !workPhone.equals("") )
  							number = workPhone;
  						if(mobilePhone != null && !mobilePhone.equals("") )
  							number = mobilePhone;
  						Contact contact = null;
  						if(mapOfContactDb.containsKey(Long.toString(contactId)));
  						{
  							 contact  = mapOfContactDb.get(Long.toString(contactId));
  						}
  						
  						if(contact==null)
  						{
  							Contact saveContact = new Contact(contactId, displayName, number);
  							db.addContact(saveContact);
  							 status=getString(R.string.join_out);
  						
  						}else if(contact.getServerid()<=0){
  						
  						    status=getString(R.string.join_out);
  						}
  						else{
  						
  							 status=getString(R.string.join_out);
  						}

  					
  						
  						if(number!=null  && !number.equals(""))
  						{
  							String firstLetter = displayName.substring(0, 1);

  	  						if (!sections.containsValue(firstLetter))
  	  						{
  	  					
  	  							sections.put(offset+i, firstLetter);
  	  						
  	  							offset++;
  	  						}else{
  	  					
  	  						}

  	  						i++;
  	  							
  	  						
  							final Object[] object = new Object[]{ Long.toString(contactId),photoPath,displayName,status};
  							getActivity().runOnUiThread(new Runnable() {
  								public void run() {
  									
  									mMatrixCursor.addRow(object);
  									mAdapter.swapCursor(mMatrixCursor);
  									mAdapter.notifyDataSetChanged();
  								}
  							});
  						
  						}
  						// Adding id, display name, path to photo and other details to cursor
  					}
  					
  				}while(contactsCursor.moveToNext());
  			}
  			
  			return mMatrixCursor;
  		}
  		
  	/*	@Override
  		protected void onPostExecute(Cursor result) {			
  			// Setting the cursor containing contacts to listview
  			mAdapter.swapCursor(result);
  		}	*/
  		
  		@Override
  		public void onPreExecute() {	
  			lockScreenOrientation();
  		}
  		
  		@Override
  		public void onPostExecute(Cursor result) {	
  
  			unLockScreenOrientation();
  		}
  		private void lockScreenOrientation()
  		{
  			
  			int currentOrientation = getResources().getConfiguration().orientation;
  			if(currentOrientation==Configuration.ORIENTATION_PORTRAIT)
  			{
  				getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  			}
  			else{
  				getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
  			}
  		}
      

		private void unLockScreenOrientation()
		{
		
				getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

		}
  }

    
    @Override
	public void onAttach(Activity activity) {
    	Log.e(TAG, "[onAttach]");
		super.onAttach(activity);
		}
    
    @Override
	public void onDetach() {
    	Log.e(TAG, "[onDetach]");
		super.onDetach();
		}

    private class ContactsCursorAdapter extends CursorSectionAdapter
	{
		private LayoutInflater	inflater;


		public ContactsCursorAdapter (Context context, int layout, Cursor c,
				String[] from, int[] to,int flats) {
			super(context, layout, c, from, to,flats);
			this.inflater = LayoutInflater.from(context);
		}
		

		@Override
		protected TreeMap<Integer, Object> initializeSections(Cursor c)
		{
			return sections;
		}

		@Override
		public int getItemViewType(int position)
		{
			if(getSections().containsKey(position))
				return 0;
			else
				return 1;
		}

		@Override
		protected boolean isSection(int position)
		{
			return getItemViewType(position) == 0;
		}

		
		

		@Override
		protected void bindSeparatorView(View v, Context context2, Object item)
		{
			Log.e(TAG, "[A");
			ListItemViewHolder holder = (ListItemViewHolder) v.getTag();

			holder.nameTextView.setText((String) item);
		}

		@Override
		protected View newSeparatorView(Context context2, Object item, ViewGroup parent)
		{
			Log.e(TAG, "[B");
			ListItemViewHolder holder = new ListItemViewHolder();
			View v;

			v = inflater.inflate(android.R.layout.simple_list_item_1, null);
			v.setTag(holder);

			holder.nameTextView = (TextView) v.findViewById(android.R.id.text1);

			return v;
		}

	}
}
